import { fromHTML, sleep, waitFor } from '../../common';
import flagIcon from '../assets/icons/flag.svg?raw';
import { offAlbumRoute, onAlbumRoute } from '../glue/routing';
import { createButtonElement } from '../glue/ui/sidebar';
import { getAlbum, getStorefronts } from '../services';

const PREFERRED_STOREFRONTS = [ 'jp', 'kr', 'us', 'de', 'fr', 'gb', 'in', 'it', 'es', 'br', 'au', 'nz', 'cn', 'hk' ];
PREFERRED_STOREFRONTS.reverse();

let globalJob: AbortController | null = null;

export const checkCountriesButtonEl = createButtonElement('Check Countries', flagIcon);

// Start checking countries when the sidebar button is clicked.
checkCountriesButtonEl.addEventListener('click', async () => {
	const refEl = document.querySelector<HTMLElement>('.section');
	if (refEl) await checkCountries(refEl);
});

// Start checking countries when the error page is shown.
onAlbumRoute(async () => {
	const errorEl = await waitFor('.page-error');
	if (errorEl) checkCountries(errorEl);
});

onAlbumRoute(() => {
	globalJob?.abort();
	globalJob = null;
});

offAlbumRoute(() => {
	globalJob?.abort();
	globalJob = null;
});

async function checkCountries(refEl: HTMLElement) {
	if (globalJob) return;
	const job = new AbortController();
	globalJob = job;

	const albumId = location.pathname.split('/')[4];

	const headerEl = fromHTML(`<div class="section ame-album-countries-header">Availability in the following storefronts:</div>`);
	const containerEl = fromHTML(`
		<div class="section ame-album-countries-container">
			<div class="ame-color-primary"></div>
			<div class="ame-color-secondary"></div>
			<div class="ame-color-tertiary"></div>
		</div>
	`);

	const primaryContainerEl = containerEl.children[0] as HTMLElement;
	const secondaryContainerEl = containerEl.children[1] as HTMLElement;
	const tertiaryContainerEl = containerEl.children[2] as HTMLElement;

	refEl.append(headerEl);
	refEl.append(containerEl);

	let storefronts = await getStorefronts();

	storefronts = storefronts
		.map(storefront => {
			storefront.attributes.name = storefront.attributes.name.split(', ').reverse().join(' ');
			return storefront;
		})
		.sort((a, b) => {
			return Math.max(PREFERRED_STOREFRONTS.indexOf(b.id), 0) - Math.max(PREFERRED_STOREFRONTS.indexOf(a.id), 0);
		});

	for (const storefront of storefronts) {
		if (job.signal.aborted) break;

		const album = await getAlbum(albumId, storefront.id);

		// Album totally unavailable.
		if (!album) {
			tertiaryContainerEl.append(fromHTML(`
				<span data-storefront="${storefront.id}" title="Totally unavailable">${storefront.attributes.name}, </span>
			`));

			await sleep(222);
			continue;
		}

		const discCount = Math.max(...album.relationships.tracks.data.map(track => track.attributes.discNumber));
		const songTracks = album.relationships.tracks.data.filter(track => track.type === 'songs');
		const otherTracks = album.relationships.tracks.data.filter(track => track.type !== 'songs');
		const unavailableTracks = new Set();
		for (let i = 1; i <= album.attributes.trackCount - otherTracks.length; i++) unavailableTracks.add(i);

		songTracks.forEach((track, i) => {
			if (!track.attributes.extendedAssetUrls) return;
			if (!track.attributes.playParams) return;
			unavailableTracks.delete(discCount > 1 ? i + 1 : track.attributes.trackNumber);
		});

		// Album partially available.
		if (unavailableTracks.size) {
			if (discCount > 1) {
				secondaryContainerEl.append(fromHTML(`
					<span data-storefront="${storefront.id}"><a target="_blank" href="https://music.apple.com/${storefront.id}/album/${albumId}" title="Partially available, missing:\n${unavailableTracks.size} tracks">${storefront.attributes.name}</a>, </span>
				`));
			} else {
				secondaryContainerEl.append(fromHTML(`
					<span data-storefront="${storefront.id}"><a target="_blank" href="https://music.apple.com/${storefront.id}/album/${albumId}" title="Partially available, missing:\n${Array.from(unavailableTracks).join(', ')}">${storefront.attributes.name}</a>, </span>
				`));
			}

			await sleep(222);
			continue;
		}

		// Album fully available.
		primaryContainerEl.append(fromHTML(`
			<span data-storefront="${storefront.id}"><a target="_blank" href="https://music.apple.com/${storefront.id}/album/${albumId}" title="Fully available">${storefront.attributes.name}</a>, </span>
		`));

		await sleep(222);
	}
}
